// Copyright (c) 2009 http://grommet.codeplex.com
// This source is subject to the Microsoft Public License.
// See http://www.opensource.org/licenses/ms-pl.html
// All other rights reserved.

using System;
using System.Ext;
using System.IO;
using System.Net.Sockets;
using System.Text;
using Grommet.Ext;
using Microsoft.SPOT;

namespace System.Net
{
    public class HttpWebResponse : WebResponse
    {
        private string response;

        public override long ContentLength { get; protected set; }
        public override string ContentType { get; protected set; }
        public override WebHeaderCollection Headers { get; protected set; }
        public override Uri ResponseUri { get; protected set; }
        public HttpStatusCode StatusCode { get; protected set; }

        internal HttpWebResponse(Uri responseUri)
        {
            this.ResponseUri = responseUri;
            Headers = new WebHeaderCollection();
        }

        internal void ReadStream(StreamReader reader)
        {
            string line;
            bool chunked = false;

            // Read response
            line = reader.ReadLine();
            string[] statusLine = line.Split(' ');
            if (statusLine[0].Substring(0, 4).ToUpper() != "HTTP")
            {
                throw new WebException(WebExceptionStatus.ServerProtocolViolation, this, string.Concat("Invalid reponse line received: ", line));
            }
            int statusCode = Convert.ToInt32(statusLine[1]);
            
            StatusCode = (HttpStatusCode)statusCode;

            // read headers 
            while (!(line = reader.ReadLine()).IsNullOrEmpty())
            {
                int index = line.IndexOf(':');
                if (index < 0)
                {
                    throw new WebException(WebExceptionStatus.ServerProtocolViolation, this, string.Concat("Invalid header received: ", line));
                }
                string name = line.Substring(0, index).Trim();
                string value = line.Substring(index + 1).Trim();
                switch (name.ToLower())
                {
                    case "content-length":
                        ContentLength = Convert.ToInt64(value);
                        break;
                    case "content-type":
                        ContentType = value;
                        break;
                    case "transfer-encoding":
                        chunked = (value.ToLower() == "chunked");
                        Headers.Add(name, value);
                        break;
                    default:
                        Headers.Add(name, value);
                        break;
                }
            }

            if (!chunked)
            {
                char[] buffer = new char[(int)ContentLength];
                int read = reader.Read(buffer, 0, (int)ContentLength);
                if (read != (int)ContentLength)
                {
                    throw new WebException(WebExceptionStatus.ReceiveFailure, this);
                }
                response = new string(buffer);
            }
            else
            {
                response = string.Empty;

                // concat lines until length is 0 (yes, this implementation is fragile,
                // but it looks like it works).  Of course, this class is a stop gap
                // messure until the real HttpWebResponse is release.
                while ((line = reader.ReadLine()).Trim()[0] != '0')
                {
                    line = reader.ReadLine();
                    response = string.Concat(response, line);
                }
            }
        }

        public override Stream GetResponseStream()
        {
            return new MemoryStream(Encoding.UTF8.GetBytes(response));
        }
    }
}
